package com.iwhalecloud.bss.kite.cucc.service.listener;

import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.attr.IGreenWayOrderService;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalErrorConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.common.util.CommonUtil;
import com.iwhalecloud.bss.kite.cucc.common.util.DateFormatUtils;
import com.iwhalecloud.bss.kite.cucc.service.attr.greenWayOrder.LocalGreenWayOrderService;
import com.iwhalecloud.bss.kite.cucc.service.even.BeforeSceneCommitEvent;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.*;
import com.iwhalecloud.bss.kite.manager.scene.service.query.QueryOfferInstContractService;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;
import com.ztesoft.bss.base.staticdata.ServiceOfferConst;
import com.ztesoft.bss.common.exception.BssException;
import com.ztesoft.bss.common.util.SpringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @ClassName : BeforeSceneCommitEventListener
 * @Description : 场景提交前事件监听器
 * <p>监听方法如果某些服务动作不需要执行，可以通过beforeSceneCommitEvent.getServiceOfferId()进行判断</p>
 * @Author : xie.zhengjun
 * @Date : 2020/9/23 17:54
 */
@Service
public class BeforeSceneCommitEventListener {

    @Resource
    private IQuerySceneInstService querySceneInstService;

    @Resource
    private QueryOfferInstContractService queryOfferInstContractService;

    @Autowired
    private OperateInstAttrService operateInstAttrService;

    /**
     * 校验必填产品属性是否为空
     * 不用修改@Order的值，默认取最大值
     *
     * @param beforeSceneCommitEvent
     */
    @EventListener
    @Order(1)
    public void checkProdAttrIsNull(BeforeSceneCommitEvent beforeSceneCommitEvent) {
        String sceneInstId = beforeSceneCommitEvent.getSceneInstId();
        if (ServiceOfferConst.service_offer_1.equals(beforeSceneCommitEvent.getServiceOfferId())) {
            List<KiteProdInst> kiteProdInsts = querySceneInstService.listProdInsts(sceneInstId);
            kiteProdInsts.forEach(kiteProdInst -> {
                List<KiteAttr> kiteAttrs = querySceneInstService
                    .listProdInstAttrs(beforeSceneCommitEvent.getCustId(), kiteProdInst.getProdInstId());
                kiteAttrs.forEach(kiteAttr -> {
                    if (KiteStringUtils.equals(kiteAttr.getIsNull(), KeyConsts.IFTRUE_F) && KiteStringUtils
                        .isEmpty(kiteAttr.getValue())) {
                        LocalErrorConsts.ATTR_NOT_NULL.throwOut(kiteAttr.getCname());
                    }
                });
            });
        }
    }

    /**
     * 校验付费关系、合同信息、收货信息必填
     *
     * @param beforeSceneCommitEvent
     */
    @EventListener
    @Order(2)
    public void checkContractAndAccountRel(BeforeSceneCommitEvent beforeSceneCommitEvent) {
        String sceneInstId = beforeSceneCommitEvent.getSceneInstId();
        List<KiteOfferInst> mainOfferInsts = this.querySceneInstService.listMainOfferInsts(sceneInstId);
        // 付费关系
        List<KiteOfferInstAcct>  accts = new ArrayList<>();
        // 合同
        List<KiteOfferInstContract> kiteOfferInstContracts = new ArrayList<>();
        // 收货信息
        List<Map<String, Object>> deliveryInfos = querySceneInstService.getExtParameterValue(sceneInstId, "offerInstDeliveryInfos");
        if (!KiteListUtils.isEmpty(mainOfferInsts)) {
            for (KiteOfferInst offerInst : mainOfferInsts) {
                accts.addAll(querySceneInstService.listOfferInstAccts(beforeSceneCommitEvent.getCustId(),
                    offerInst.getOfferInstId()));
                kiteOfferInstContracts.addAll(queryOfferInstContractService
                    .listOfferInstContracts(beforeSceneCommitEvent.getCustId(), offerInst.getOfferInstId()));
            }
        }
        accts.removeIf(acct -> KiteStringUtils.equalsAny(acct.getActionType().name(), ActionType.D.name(), ActionType.X.name()));
        kiteOfferInstContracts.removeIf(kiteOfferInstContract ->
            KiteStringUtils.equalsAny(kiteOfferInstContract.getActionType().name(), ActionType.D.name(), ActionType.X.name())
        );
        if (KiteListUtils.isEmpty(accts)) {
            LocalErrorConsts.ACCT_REL_NOT_NULL.throwOut();
        }
        int count = (int) accts.stream().filter(acct -> "1".equals(acct.getIsDefault())).count();
        if (1 != count) {
            LocalErrorConsts.DEFAULT_ACCT_REL_ONLY.throwOut(count);
        }
        if (KiteListUtils.isEmpty(kiteOfferInstContracts)) {
            LocalErrorConsts.CONTRACT_NOT_NULL.throwOut();
        }
        //业务变更不校验收货信息
        String busiChangeScene = querySceneInstService.getExtParameterValue(sceneInstId, LocalKeyConsts.BUSI_CHANGE_SCENE);
        if (KiteListUtils.isEmpty(deliveryInfos) && !KeyConsts.IFTRUE_T.equals(busiChangeScene)) {
            LocalErrorConsts.DELIVERYINFO_NOT_NULL.throwOut();
        }
    }

    /**
             * 业务变更，校验操作类型不能为空
     *
     * @param beforeSceneCommitEvent
     */
    @EventListener
    @Order(3)
    public void checkBusnessType(BeforeSceneCommitEvent beforeSceneCommitEvent) {
        String sceneInstId = beforeSceneCommitEvent.getSceneInstId();
        String serviceOfferId = beforeSceneCommitEvent.getServiceOfferId();
        if (KiteStringUtils.isEqual(ServiceOfferConst.service_offer_2826, serviceOfferId)) {
            //获取页面勾选的操作类型
            List<String> serviceOfferIdList = querySceneInstService.getExtParameterValue(sceneInstId, "BUSI_CHANGE_SERVICEOFFERID");
            if (KiteListUtils.isEmpty(serviceOfferIdList)) {
                LocalErrorConsts.BUSINESS_TYPE_NOT_NULL.throwOut();
            }
        }
    }

    /**
     * 设置APN名称
     *
     * @param beforeSceneCommitEvent
     */
    @EventListener
    @Order(4)
    public void setApnName(BeforeSceneCommitEvent beforeSceneCommitEvent) {
        String sceneInstId = beforeSceneCommitEvent.getSceneInstId();
        if (ServiceOfferConst.service_offer_1.equals(beforeSceneCommitEvent.getServiceOfferId())) {
            List<KiteInst> insts = querySceneInstService
                .listInsts(sceneInstId, Collections.singletonList(InstType.PROD_INST_FUNC)).stream().filter(inst -> !KiteStringUtils.equalsAny(inst.getActionType().name(), ActionType.X.name(), ActionType.D.name())).collect(Collectors.toList());
            insts.forEach(kiteInst -> {
                // 新增APN方式
                String newApnType = kiteInst.getAttrValue("200003996");
                // 如果新增APN方式为 使用共享APN 或 使用已创建APN 则将APN名称的值设为APN域名的值
                String apnDomainName = null;
                if (KiteStringUtils.equalsAny(newApnType, "100006950")) {
                    apnDomainName = kiteInst.getAttrValueDesc("200003997");
                }
                if (KiteStringUtils.equalsAny(newApnType, "100006951")) {
                    apnDomainName = kiteInst.getAttrValue("200003998");
                }
                if (KiteStringUtils.isNotEmpty(apnDomainName)) {
                    OperateInstAttrService operateInstAttrService = SpringUtil.getBean(OperateInstAttrService.class);
                    Optional.ofNullable(kiteInst.getAttr("200002833")).ifPresent(kiteAttr -> {
                        kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_H);
                    });
                    // APN名称
                    operateInstAttrService.setAttrValue(kiteInst, "200002833", apnDomainName, sceneInstId, null);
                    Optional.ofNullable(kiteInst.getAttr("200004135")).ifPresent(kiteAttr -> {
                        kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_H);
                    });
                    // APN标识
                    operateInstAttrService.setAttrValue(kiteInst, "200004135", apnDomainName, sceneInstId, null);
                }
            });
        }
    }

    /**
     * 绿色工单校验
     * @param beforeSceneCommitEvent
     */
    @EventListener
    @Order(5)
    public void greenWayOrderCheck(BeforeSceneCommitEvent beforeSceneCommitEvent) {
        String sceneInstId = beforeSceneCommitEvent.getSceneInstId();
        String custId = beforeSceneCommitEvent.getCustId();
        String serviceOfferId = beforeSceneCommitEvent.getServiceOfferId();

        KiteSceneInst kiteSceneInst = querySceneInstService.getSceneInst(sceneInstId);
        String rootInstId = kiteSceneInst.getRootInstId();
        String cateId = querySceneInstService.getOfferInstAttrValue(custId, rootInstId, "cateId");

        LocalGreenWayOrderService service = SpringUtil.getBean(LocalGreenWayOrderService.class);
        IGreenWayOrderService handler = service.getHandlerByCateId(cateId);
        if (Objects.nonNull(handler)) {
            handler.check(sceneInstId, custId);
        }
    }

    /**
     * Description: 产品属性修改以后，需要修改服务开始时间 <br>
     *
     * @author tengg<br>
     * @taskId <br>
     * @param beforeSceneCommitEvent <br>
     */
    @EventListener
    @Order(6)
    public void setServiceStartDate(BeforeSceneCommitEvent beforeSceneCommitEvent) {
        /*String serviceOfferId = beforeSceneCommitEvent.getServiceOfferId();
        if (!KiteStringUtils.isEqual(serviceOfferId, ServiceOfferConst.service_offer_2826)) {
            return;
        }
        String sceneInstId = beforeSceneCommitEvent.getSceneInstId();
        String custId = beforeSceneCommitEvent.getCustId();
        List<KiteInst> kiteProdInsts = querySceneInstService.listInsts(sceneInstId, Arrays.asList(InstType.PROD_INST));
        if (KiteListUtils.isEmpty(kiteProdInsts)) {
            return;
        }

        kiteProdInsts.forEach(prodInst ->{
            List<KiteAttr> prodAttrs = prodInst.listAttrs();
            //服务开始时间属性
            KiteAttr startDateAttr = prodInst.getAttr("200002505");
            if (Objects.nonNull(startDateAttr)) {
                for (KiteAttr attr : prodAttrs) {
                    if(!KiteStringUtils.isEqual(attr.getShowType(),KeyConsts.PROD_ATTR_SHOW_TYPE_E)){
                        if (!KiteStringUtils.isEqual(attr.getOriginValue(), attr.getValue())) {
                            operateInstAttrService.setAttrValue(prodInst, startDateAttr.getFieldName(), DateFormatUtils.getFirstDayInNextMonth(DateFormatUtils.getFormatedDateTime(), DateFormatUtils.DATE_FORMAT), sceneInstId, null);
                            return;
                        }
                    }
                }
                List<KiteProdInstFunc> prodInstFuncList = querySceneInstService.listProdInstFuncs(custId, prodInst.getInstId());
                for (KiteProdInstFunc prodInstFunc : prodInstFuncList) {
                    if (!KiteStringUtils.isEqual(prodInstFunc.getActionType().name(), ActionType.K.name())) {
                        operateInstAttrService.setAttrValue(prodInst, startDateAttr.getFieldName(), DateFormatUtils.getFirstDayInNextMonth(DateFormatUtils.getFormatedDateTime(), DateFormatUtils.DATE_FORMAT), sceneInstId, null);
                        return;
                    }
                }
            }
        });*/
    }

    /**
     * 追单  判断是否有内容改变
     * @param beforeSceneCommitEvent
     */
    @EventListener
    @Order(7)
    public void isChangeCheck(BeforeSceneCommitEvent beforeSceneCommitEvent) {
        String serviceOfferId = beforeSceneCommitEvent.getServiceOfferId();
        if (!KiteStringUtils.isEqual(serviceOfferId, LocalServiceOfferConsts.SERVICE_OFFER_FOLLOW)) {
            return;
        }
        String sceneInstId = beforeSceneCommitEvent.getSceneInstId();
        //TODO 考虑现有逻辑只针对业务信息进行校验,那么除订购和产品变更外的业务暂不校验,后续明确校验逻辑后去掉这个过滤
        String upServiceOfferId = querySceneInstService.getExtParameterValue(sceneInstId, "upServiceOfferId");
        String bizType = querySceneInstService.getExtParameterValue(sceneInstId, "bizType");
        if (!KiteStringUtils.equalsAny(bizType, "1001", "1012") && KiteStringUtils.isEmpty(upServiceOfferId)) {
            return;
        }
        List<KiteInst> kiteProdInsts = querySceneInstService.listInsts(sceneInstId, Arrays.asList(InstType.PROD_INST));
        List<KiteInst> kiteInsts = querySceneInstService.listInsts(sceneInstId, Arrays.asList(InstType.PROD_INST_FUNC));

        // 追单，记录初始化的 instId，非本次追单新增
        String prodFollowInstIds = querySceneInstService.getExtParameterValue(sceneInstId, "prodFollowInstIds");

        AtomicBoolean flag = new AtomicBoolean(false);
        kiteProdInsts.forEach(prodInst -> {
            if (!KiteStringUtils.equalsAny(prodInst.getActionType().name(), ActionType.K.name(), ActionType.X.name())) {
                if(!KiteStringUtils.isEqual(prodInst.getActionType().name(), ActionType.A.name()) || !CommonUtil.splitContains(prodFollowInstIds, prodInst.getInstId())) {
                    flag.set(true);
                    return;
                }
            }
            List<KiteAttr> prodAttrs = prodInst.listAttrs();
            for (KiteAttr attr : prodAttrs) {
                if (!KiteStringUtils.isEqual(attr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_E)) {
                    if (!KiteStringUtils.isEqual(attr.getOldValue(), attr.getValue())) {
                        flag.set(true);
                        return;
                    }
                }
            }

        });
        if (flag.get()) {
            return;
        }
        kiteInsts.forEach(kiteInst -> {
            if (!KiteStringUtils.equalsAny(kiteInst.getActionType().name(), ActionType.K.name(), ActionType.X.name())) {
                flag.set(true);
                return;
            }
            List<KiteAttr> kiteAttrs = kiteInst.listAttrs();
            for (KiteAttr attr : kiteAttrs) {
                if (!KiteStringUtils.isEqual(attr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_E)) {
                    if (!KiteStringUtils.isEqual(attr.getOldValue(), attr.getValue())) {
                        flag.set(true);
                        return;
                    }
                }
            }
        });
        if (flag.get()) {
            return;
        }

        // 追单，记录初始化的 instId，非本次追单新增
        String offerFollowInstIds = querySceneInstService.getExtParameterValue(sceneInstId, "offerFollowInstIds");

        List<KiteInst> additionalInsts = querySceneInstService.listInsts(sceneInstId, Arrays.asList(InstType.ADDITIONAL_OFFER_INST));
        additionalInsts.forEach(additionalInst -> {
            // 先新增后删除的情况，忽略
            if (KiteStringUtils.isEqual(additionalInst.getActionType().name(), ActionType.X.name()) && KiteStringUtils.isEqual(additionalInst.getOriginalActionType().name(), ActionType.A.name()) && !CommonUtil.splitContains(offerFollowInstIds, additionalInst.getInstId())) {
                return;
            }

            if (!KiteStringUtils.equalsAny(additionalInst.getActionType().name(), ActionType.K.name(), ActionType.X.name())) {
                if(!KiteStringUtils.isEqual(additionalInst.getActionType().name(), ActionType.A.name()) || !CommonUtil.splitContains(offerFollowInstIds, additionalInst.getInstId())) {
                    flag.set(true);
                    return;
                }
            }
            List<KiteAttr> kiteAttrs = additionalInst.listAttrs();
            for (KiteAttr attr : kiteAttrs) {
                if (!KiteStringUtils.isEqual(attr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_E)) {
                    if (!KiteStringUtils.isEqual(attr.getOldValue(), attr.getValue())) {
                        flag.set(true);
                        return;
                    }
                }
            }
        });
        if (!flag.get()) {
            BssException.throwOut("", "", "没有变更任何业务信息，无法发起追单");
        }
    }

    /**
     * 合同信息校验
     *
     * @param beforeSceneCommitEvent
     */
    @EventListener
    @Order(8)
    public void checkContractInfo(BeforeSceneCommitEvent beforeSceneCommitEvent) {
        String serviceOfferId = beforeSceneCommitEvent.getServiceOfferId();
        if (KiteStringUtils.equals(serviceOfferId,LocalServiceOfferConsts.PAY_RELATION_MANAGMENT)) {
            return;
        }
        String sceneInstId = beforeSceneCommitEvent.getSceneInstId();
        List<KiteOfferInst> mainOfferInsts = this.querySceneInstService.listMainOfferInsts(sceneInstId);
        // 合同
        List<KiteOfferInstContract> kiteOfferInstContracts = new ArrayList<>();
        if (!KiteListUtils.isEmpty(mainOfferInsts)) {
            for (KiteOfferInst offerInst : mainOfferInsts) {
                kiteOfferInstContracts.addAll(queryOfferInstContractService
                    .listOfferInstContracts(beforeSceneCommitEvent.getCustId(), offerInst.getOfferInstId()));
            }
        }
        kiteOfferInstContracts.removeIf(kiteOfferInstContract -> ActionType.X.name().equals(kiteOfferInstContract.getActionType().name()));

        kiteOfferInstContracts = kiteOfferInstContracts.stream()
            .filter(contract -> !KiteStringUtils.equalsAny(contract.getActionType().name(),ActionType.X.name(),ActionType.D.name()))
            .collect(Collectors.toList());
        kiteOfferInstContracts.forEach(offerInstContractRel -> {
            if (KiteStringUtils.isEmpty(offerInstContractRel.getContractType())) {
                BssException.throwOut(KeyConsts.LOG_MODULE, "","当前合同缺少合同类型，请更换合同或重新上传合同");
            }
        });
    }
}
